/*
Chris Elrod
10/27/2008
CSci 252
Prof. Hasan

Project 2 - EJB

Reference: 
    BEA trader example: BEA 10.3 HOME\wlserver_10.3\samples\server\examples\src\examples\ejb\ejb20\basic\statefulSession
*/

package examples.ejb.ejb20.basic.Project2;

import javax.ejb.CreateException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import weblogic.ejbgen.*;
import java.io.File;
import java.io.FileReader;
import java.io.BufferedReader;
import java.io.FileWriter;
import java.io.BufferedWriter;
import java.util.Scanner;
import java.util.regex.Pattern;
import java.util.Hashtable;
import java.util.Enumeration;


/**
 * FacadeBean is a stateful Session Bean. This bean illustrates:
 * 
 * Automatic persistence of state between calls to the Session Bean.
 * Looking up values from the Environment.
 * 
 */


@FileGeneration(remoteClass = Constants.Bool.TRUE,
                localHome = Constants.Bool.FALSE,
                remoteHome = Constants.Bool.TRUE,
                remoteClassName = "Inventory",
                remoteHomeName = "InventoryHome",
                localClass = Constants.Bool.FALSE)
@JarSettings(ejbClientJar = "Project2_client.jar")
@JndiName(remote = "Project2-Inventory-InventoryHome")
@Session(idleTimeoutSeconds = "600",
         maxBeansInCache = "1000",
         transTimeoutSeconds = "0",
         type = Session.SessionType.STATEFUL,
         defaultTransaction = Constants.TransactionAttribute.REQUIRED,
         ejbName = "statelessSession_Inventory",
         enableCallByReference = Constants.Bool.TRUE)


public class InventoryBean implements SessionBean {


  private SessionContext ctx;
  private Hashtable stock = new Hashtable();


  public InventoryBean(){
    /*Debugging code:

    this.stock.put( new String("12344*Operating Sytems"), new Integer("33") );
    this.stock.put( new String("14567*Computer Networks"), new Integer("9683") );
    this.stock.put( new String("12344*Mastering EJB"), new Integer("33") );
    this.stock.put( new String("12344*Algorithms"), new Integer("223") );*/
  }


  /*A utility logger.  Parmeters: the message to be logged.  Returns: void*/

  private void log(String s) {
    System.out.println(s);
  } 

  
  /**
   * This method is required by the EJB Specification,
   * but is not used by this example.
   */

  public void ejbActivate() {
    log("ejbActivate called");
  }


  /**
   * This method is required by the EJB Specification,
   * but is not used by this example.
   */

  public void ejbRemove() {
    log("ejbRemove called");
  }


  /**
   * This method is required by the EJB Specification,
   * but is not used by this example.
   */

  public void ejbPassivate() {
    log("ejbPassivate called");
  }


  /**
   * 
   * This method is required by the EJB Specification,
   * but is not used by this example.
   *
   * Sets the session context.
   *
   * @param ctx - SessionContext Context for session
   */

  public void setSessionContext(SessionContext ctx) {
    log("setSessionContext called");
    this.ctx = ctx;
  }


  /**
   * 
   *
   * This method corresponds to the create method in the home interface
   * "InventoryHome.java".
   * The parameter sets of the two methods are identical. When the client calls
   * <code>InventoryHome.create()</code>, the container allocates an instance of 
   * the EJBean and calls <code>ejbCreate()</code>.
   *
   * @exception - javax.ejb.CreateException if there is a communications or systems failure
   *
   * @see - examples.ejb.ejb20.basic.Project2.Inventory
   */

  public void ejbCreate () throws CreateException {
    log("ejbCreate called");

    try {
      InitialContext ic = new InitialContext();
    } catch (NamingException ne) {
      throw new CreateException("Failed to find environment value "+ne);
    }
  }


  /*Does the work of adding stock, with respect to the project requirements.
   *Logs the stock hastable ( the inventory) to check the success of the code.
   *
   *Parms: pub_id, title and qty.  Returns: success boolean.*/ 

  @RemoteMethod()
  
  public boolean add( String pub_id, String title, int qty ){

    if (stock.containsKey(pub_id + "*" + title) ){
          Integer temp = (Integer) stock.get(pub_id + "*" + title);
          temp = temp + qty; 
          stock.remove(pub_id + "*" + title);
          stock.put( pub_id + "*" + title, new Integer(temp) );	   
    }else{
          stock.put( pub_id + "*" + title, new Integer(qty) );           
    }       

    log("Stock after a call to Inventory's add: " + stock.toString());
    log("ISBN " + getISBN(title) + " for title, " + title + " has been added to the inventory."  );

    return true; 
  }


  /*Does the work of adding stock, with respect to the project requirements.
   *Logs the stock hastable ( the inventory) to check the success of the code.
   *
   *Parms: pub_id, title and qty.  Returns: success boolean.*/ 
 
  @RemoteMethod()
  
  public boolean remove( String pub_id, String title, int qty ){
            
    if (stock.containsKey(pub_id + "*" + title) ){
          Integer temp = (Integer) stock.get(pub_id + "*" + title);
          temp = temp - qty;

          if(temp <= 0){           
            stock.remove(pub_id + "*" + title);
            return false;
          }else{ 
            stock.remove(pub_id + "*" + title);
            stock.put( pub_id + "*" + title, new Integer(temp) );
            log("Stock after a call to Inventory's remove: " + stock.toString());
            return true;	   
          }
    }else{
          log("Stock after a call to Inventory's remove: there is nothing in stock to remove.");
          return false;           
    }       

  }


  /*
   *Satisfies the project's requirement of have a getISBN in the InventoryBean.
   *Logs the stock hastable ( the inventory) to check the success of the code.
   *
   *Parms: title.  Returns: success String (ISBN).
   *
   *Note - The getISBN here and the getISBN in Transaction are disjoint:
   *  each checks their respective hashtable.
   */ 

  @RemoteMethod()
  
  public String getISBN (String title) {

      for (Enumeration e = stock.keys() ; e.hasMoreElements() ;) {

        String temp = new String( e.nextElement().toString() );
        Scanner sc = new Scanner( temp );
        sc.useDelimiter( Pattern.compile("\\*") );
        String temp2 = sc.next();   
        if ( sc.next().equals(title) ){
             return temp2;
        }

      }

      return null;  
  }

}





